#include "socket_client.h"

bool SocketClient::connectToServer() {
    std::lock_guard<std::mutex> lock(mutex_);
    if (is_connected_) {
#if OHOS_PLATFORM
        OH_LOG_INFO(LOG_APP, "Already connected to server.");
#else
        printf("Already connected to server.");
#endif
        return true;
    }

    // 1. 创建 socket
    sock_ = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_ < 0) {
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Socket creation failed.");
#else
        printf("Socket creation failed.");
#endif
        return false;
    }
    // 2. 绑定客户本地端口号
    struct sockaddr_in local_addr;
    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_port = htons(CLIENT_PORT);

    if (bind(sock_, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
        int err = errno;
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Bind failed. errno=%{public}d: %{public}s", err, strerror(err));
#else
        printf("Bind failed. errno=%d: %s", err, strerror(err));
#endif
        close(sock_);
        return false;
    }
    // 3. 设置目标服务器地址
    
    memset(&server_addr_, 0, sizeof(server_addr_));
    server_addr_.sin_family = AF_INET;
    server_addr_.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &server_addr_.sin_addr) <= 0) {
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Invalid address.");
#else
        printf("Invalid address.");
#endif
        return false;
    }
    // 尝试连接到服务器
    if (connect(sock_, (struct sockaddr *)&server_addr_, sizeof(server_addr_)) < 0) {
        int err = errno;
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Connection failed! errno=%{public}d: %{public}s", err, strerror(err));
#else
        printf("Connection failed! errno=%d: %s", err, strerror(err));
#endif
        return false;
    }

    is_connected_ = true;
#if OHOS_PLATFORM
    OH_LOG_INFO(LOG_APP, "SocketClient Connected to server: %{public}s: %{public}d", SERVER_IP, SERVER_PORT);
#else
    printf("SocketClient Connected to server: %s: %s", SERVER_IP, SERVER_PORT);
#endif
    sendData("send data");
    // 启动接收数据线程
    receiving_thread_ = std::thread(&SocketClient::receiveDataThread, this);
    return true;
}

void SocketClient::sendData(const std::string &message) {
    std::lock_guard<std::mutex> lock(mutex_);
    if (!is_connected_) {
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Not connected to server. Cannot send data.");
#else
        printf("Not connected to server. Cannot send data.");
#endif
        return;
    }
    send(sock_, message.c_str(), message.size(), 0);
#if OHOS_PLATFORM
    OH_LOG_INFO(LOG_APP, "Message sent: %{public}s", message.c_str());
#else
    printf("Message sent: %s", message.c_str());
#endif
}

void SocketClient::disconnect() {
    std::lock_guard<std::mutex> lock(mutex_);
    if (is_connected_) {
        is_connected_ = false;
        close(sock_);
        if (receiving_thread_.joinable()) {
            receiving_thread_.join(); // 等待接收线程结束
        }
        std::cout << "Disconnected from server." << std::endl;
#if OHOS_PLATFORM
        OH_LOG_INFO(LOG_APP, "Disconnected from server.");
#else
        printf("Disconnected from server.");
#endif
    }
}

void SocketClient::receiveDataThread() {
    char buffer[1024];
    while (is_connected_) {
        memset(buffer, 0, sizeof(buffer));
        int bytes_received = recv(sock_, buffer, sizeof(buffer) - 1, 0);
        if (bytes_received > 0) {
            buffer[bytes_received] = '\0'; // 确保字符串结束
            std::string receive_data(buffer);
#if OHOS_PLATFORM
            OH_LOG_INFO(LOG_APP, "Received response: %{public}s", buffer);
#else
            printf("Received response: %s", buffer);
#endif
            if (data_received_callback_) {
                data_received_callback_(receive_data);
            }
        } else {
#if OHOS_PLATFORM
            OH_LOG_ERROR(LOG_APP, "Server disconnected or error occurred.");
#else
            printf("Server disconnected or error occurred.");
#endif
            disconnect();
        }
    }
}